#ifndef  __STREAM_H__
#define  __STREAM_H__

//#include "Font.h"
#include "Memory.h"
#include "ResFile.h"
#include "../GameCommon.h"
// C Headers
#include <stdio.h>
#define TEXT_FILENAME_SIZE 1024
class CFileStream
{
    friend class CMemoryStream;
public:
	typedef void (*Function)(void* object, CFileStream *pFS);

	CFileStream();
	~CFileStream(void);

	bool OpenForRead(const char * filename);
	bool OpenForWrite(const char * filename);
	void Close();

    bool Write(void *data, unsigned long len);
	bool Read(void *data, unsigned long len);

	long GetSize();
	bool Seek(long offset, int origin);

	inline void* getData(){return mBuffer;}
	inline int getLength(){return miLength;}


private:
	bool mIsOpen;					// The file open?
	FILE* mFileID;					// The file handler
	static char _AppPath[TEXT_FILENAME_SIZE];
public:
	char mFilename[TEXT_FILENAME_SIZE];				// The filename
	char * mBuffer;					// The internal buffer
	int miLength;					// Len of the buffer
	int miOffset;					// Current offset
	Function mFunction;				// Pointer to the function that load the file
	void * mObject;					// Pointer to the object
	void * mpUseData;				// User buffer

	static void setAppPath(char *);
	static void getResourcePath(const char *res, char *out);
};

class CMemoryStream
{
public:
	CMemoryStream(char* buf, unsigned long size);
	CMemoryStream() : mpData(NULL), miPosition(0), miLength(0), mbNeedFreeBuffer(false) {}
	~CMemoryStream();

	int Read(void* out,  long  size);
	int Write(void* in,  long  size);
	int Seek(int offset, int type);
	int SetPosition(int pos);
    void Attach(CFileStream& fs);
    void AttachCopy(CFileStream& fs);
	void ReleaseData();
	char* Detach(){mbNeedFreeBuffer = false; return mpData;}
	//static CMemoryStream* CreateFromFile(const char* filename);


	unsigned char	ReadUChar();
	short			ReadShort();
	short			ReadShortBE();
	int             ReadInt(){return ReadIntLE();}
	int             ReadIntLE();
	unsigned        ReadUIntLE(){ return ReadIntLE();}

	inline void* getData(){return mpData;}
	inline int getLength(){return miLength;}
	inline int getPosition(){return miPosition;}

	int Seek(int offset);

	char* mpData;
	int miPosition;
	int miLength;
	bool mbNeedFreeBuffer;
};

template <typename T>
void Read(const char* filename, T *object, void* user_data=NULL, long len = -1)
{
	CResFile* pPack = NULL;
	void* hRecord = NULL;
	char fullfilename[TEXT_FILENAME_SIZE];
	int numResPacks = sizeof(_resPack)/sizeof(_resPack[0]);

	for(int i=0; i< numResPacks; ++i)
	{
		hRecord = _resPack[i].FindRecord(filename);
		if(hRecord)
		{
			pPack = &_resPack[i];
			break;
		}
	}

	// RUIZD: Remove the first slash if it's present
	if (filename[0] == '\\') filename++;
	printf("%s\n", filename);
	if (hRecord)
	{
		int len = pPack->GetRecordSize(hRecord);
		//ASSERT(len>0);
		char *pBuf = GL_NEW char[len];
		//if (!pBuf) pBuf = GL_NEW char[len];
		//ASSERT(pBuf);
		//temp used
		CFileStream *pFS = GL_NEW CFileStream();
		pFS->mpUseData = user_data;

		strcpy(pFS->mFilename, filename);

		pFS->mBuffer  = pBuf;
		pFS->miLength = len;
		pFS->mObject  = object;
		
		pFS->mFunction=  T::LoadFile;
		//pFS->mFunction=  CResFile::LoadFile;

		pFS->miOffset = 0;
		pPack->ReadRecord(hRecord, pBuf, len);
		
		T::LoadFile(object,pFS);
		//CResFile::LoadFile(object, pFS);

		delete pFS;
	}
	else
	{
		nCGame::GetFileName(filename, false, fullfilename);
		//sprintf(fullfilename, "%s", filename);
		// RUIZD: Code added for iPhone version
		CFileStream *pFS = GL_NEW CFileStream();

		// RUIZD: The OpenForRead, open the file, creates a buffer for all the content of the file
		// and put all the content in it
		pFS->OpenForRead(fullfilename);

		pFS->mpUseData = user_data;
		strcpy(pFS->mFilename, fullfilename);
		pFS->mObject  = object;
		pFS->mFunction=  T::LoadFile;
		pFS->miOffset = 0;

		(*T::LoadFile)(object, pFS);

		// RUIZD: Don't close the stream right now
		// Close the FileStream
		pFS->Close();
		delete pFS;
	}
}
#endif
